/*
 * Copyright (c) 2021 Huawei Device Co.,  Ltd.
 * Licensed under the Apache License,  Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,  software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,  either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cashdevice_proxy.h"
#include <ipc_types.h>
#include <message_option.h>
#include <message_parcel.h>
#include <string.h>
#include "hilog_wrapper.h"
#include "cashdevice_errors.h"
#include "cashdevice_common.h"
#include "parcelable_vector_rw.h"

namespace SwanLink {
namespace Finance {
using namespace OHOS;

std::vector<DevAccess> CashDeviceSrvProxy::GetSupportAccess()
{
    std::vector<DevAccess> result;
    sptr<IRemoteObject> remote = remote_impl_;
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    if (!data.WriteInterfaceToken(descritor_)) {
        COMMON_HILOGE(COMMON_SRV,  "Write descriptor failed");
        return result;
    }
    int ret = remote->SendRequest(static_cast<int>(
        ICashDeviceSrv::CASHDEVICE_GETSUPPORTACCESS),
        data,  reply,  option);

    if (ret != ERR_OK) {
        COMMON_HILOGE(COMMON_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    if ( !ReadVectorFromParcel<DevAccess>(reply,  result) ) {
        COMMON_HILOGE(COMMON_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }

    return result;
}

int CashDeviceSrvProxy::Open(const std::string& name, const Transport& trans)
{
    int result = -1;
    sptr<IRemoteObject> remote = remote_impl_;
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    if (!data.WriteInterfaceToken(descritor_)) {
        std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,
            char16_t> convert;
        std::string a = convert.to_bytes(descritor_);
        COMMON_HILOGE(COMMON_SRV, "Write descriptor failed, %{public}s", a.c_str());
        return result;
    }

    WRITE_PARCEL_WITH_RET(data, String, name, -1);
    WRITE_BUFFER_WITH_RET(data, Buffer, &trans, sizeof(trans), -1);

    int ret = remote->SendRequest(static_cast<int>(
        ICashDeviceSrv::CASHDEVICE_OPEN), data, reply, option);

    if (ret != ERR_OK) {
        COMMON_HILOGE(COMMON_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int CashDeviceSrvProxy::Close(int handle)
{
    int result = -1;
    sptr<IRemoteObject> remote = remote_impl_;
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    if (!data.WriteInterfaceToken(descritor_)) {
        std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,
            char16_t> convert;
        std::string a = convert.to_bytes(descritor_);
        COMMON_HILOGE(COMMON_SRV,  "Write descriptor failed, %{public}s", a.c_str());
        return result;
    }

    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);

    int ret = remote->SendRequest(static_cast<int>(
        ICashDeviceSrv::CASHDEVICE_CLOSE),  data,  reply,  option);

    if (ret != ERR_OK) {
        COMMON_HILOGE(COMMON_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int CashDeviceSrvProxy::QueryStatus(int handle, int module, char *err)
{
    int result = -1;
    sptr<IRemoteObject> remote = remote_impl_;
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    if (!data.WriteInterfaceToken(descritor_)) {
        COMMON_HILOGE(COMMON_SRV,  "Write descriptor failed");
        return result;
    }

    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, module, -1);
    int ret = remote->SendRequest(static_cast<int>(ICashDeviceSrv::CASHDEVICE_QUERYSTATUS),  data,  reply,  option);

    if (ret != ERR_OK) {
        COMMON_HILOGE(COMMON_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    std::string str_err;
    READ_PARCEL_WITH_RET(reply, String, str_err, -1);
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);
    strncpy(err, str_err.c_str(), str_err.length());

    return result;
}

int CashDeviceSrvProxy::Reset(int handle)
{
    int result = -1;
    sptr<IRemoteObject> remote = remote_impl_;
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    if (!data.WriteInterfaceToken(descritor_)) {
        COMMON_HILOGE(COMMON_SRV,  "Write descriptor failed");
        return result;
    }

    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);

    int ret = remote->SendRequest(static_cast<int>(ICashDeviceSrv::CASHDEVICE_RESET),  data,  reply,  option);

    if (ret != ERR_OK) {
        COMMON_HILOGE(COMMON_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}
}  // namespace Finance
}   // namespace SwanLink
